package com.huatai.datacenter.websocket;

import cn.hutool.extra.spring.SpringUtil;
import com.huatai.datacenter.entity.DataSourceEntity;
import com.huatai.datacenter.service.DataSourceService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;

/**
 * @author Lion
 * @date 2023/3/22  14:22
 */
@Slf4j
@Component
@ServerEndpoint("/socket/{clientId}")
public class WebSocketServer {

	//用来存放每个客户端对应的webSocket对象，适用于同时与多个客户端通信
	public static CopyOnWriteArraySet<WebSocketServer> webSocketSet = new CopyOnWriteArraySet<WebSocketServer>();

	//服务端与指定客户端通信的话，使用map来存放，其中key为用户标识
	public static final ConcurrentHashMap<Session, Object> webSocketMap = new ConcurrentHashMap<Session, Object>();

	//与某个客户端的连接会话，通过session实现定向推送（只推送给某个用户）
	private Session session;

	//客户端请求地址
	private String clientId;

	@Autowired
	private DataSourceService dataSourceService = SpringUtil.getBean(DataSourceService.class);

	/**
	 * @author Lion
	 * @description 连接建立成功调用的方法
	 * @param session
	 * @return void
	 */
	@OnOpen
	public void onOpen(Session session, @PathParam("clientId") final String clientId){
		this.session = session;
		this.clientId = clientId;
		webSocketSet.add(this);
		webSocketMap.put(session,this);
		sendMessageByClientId();
	}

	/**
	 * @author Lion
	 * @description 连接关闭调用的方法
	 * @param closeSession
	 * @return void
	 */
	@OnClose
	public void onClose(Session closeSession){
		webSocketSet.removeIf((WebSocketServer w) -> w.getSession().equals(closeSession));
		//webSocketSet.remove(closeSession);
		webSocketMap.remove(closeSession);
	}

	@OnMessage
	public void onMessage(String message,Session mySession) {

		log.info("来自客户端的消息：" + message);
		for (Session session : webSocketMap.keySet()){
			if (session.equals(mySession)){
				WebSocketServer item = (WebSocketServer)webSocketMap.get(mySession);
				String msg = "来自服务端的消息";
				item.sendMessage(mySession,msg);
			}
		}
	}

	/**
	 * @author Lion
	 * @description 发生错误时调用
	 * @param session
	 * @param error
	 * @return void
	 */
	@OnError
	public void onError(Session session, Throwable error){
		log.info("发生错误");
	}

	/**
	 * @author Lion
	 * @description 给所有客户端发送消息
	 * @param  message
	 * @return void
	 */
	public void sendAllMessage(String message){
		try {
			this.session.getBasicRemote().sendText(message);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * @author Lion
	 * @description 定向发送数据
	 * @param session
	 * @param message
	 * @return void
	 */
	public void sendMessage(Session session,String message){
		synchronized (this){
			if (session.isOpen()){
				try {
					session.getBasicRemote().sendText(message);
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	public void sendMessageByClientId(){
		if ("queryData".equals(clientId)){
			List<DataSourceEntity> entityList = dataSourceService.list();
			for (int i=0;i<entityList.size();i++){

				sendMessage(session,entityList.get(i).toString());
			}
		}
	}

	public Session getSession() {
		return session;
	}

	public String getClientId() {
		return clientId;
	}
}
